package com.liao.intimacy;

import com.liao.converter.impl.DimensionConverter;
import com.liao.kv.base.BaseDimension;
import com.liao.kv.key.ContactDimension;
import com.liao.kv.key.DateDimension;
import com.liao.util.JDBCCacheBean;
import com.liao.util.JDBCUtil;
import com.liao.util.LRUCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Converter {

    //日志记录类，注意导包的正确性
    private static final Logger logger = LoggerFactory.getLogger(DimensionConverter.class);
    //每个线程保留自己的Connection实例
    private ThreadLocal<Connection> threadLocalConnection = new ThreadLocal<>();
    //创建数据缓存队列
    private LRUCache<String, Integer> lruCache = new LRUCache(3000);//3000条

    public Converter() {
        // JVM虚拟机关闭时，尝试关闭数据库连接
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            logger.info("stopping mysql connection...");
            JDBCUtil.close(threadLocalConnection.get(), null, null);
            logger.info("mysql connection is successfully closed");
        }));
    }

    private Connection getConnection() throws SQLException {
        Connection conn = null;
        synchronized (this) {
            conn = JDBCCacheBean.getInstance();
            if (conn == null || conn.isClosed() || conn.isValid(3)) {
                conn = JDBCCacheBean.getInstance();
            }
            threadLocalConnection.set(conn);
        }
        return conn;
    }

    private int execSQL(Connection conn, String sql, String phone_num) {
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setString(1,phone_num);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                return resultSet.getInt(1);//直接返回id
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.close(null, preparedStatement, resultSet);
        }
        throw new RuntimeException("Failed to get id which matches the phonenumber");
    }

    public int getPhoneId(String phone_num) throws IOException {
        int id=0;
        String sql="select `id` from `tb_contacts` where `telephone` = ?";
        if (lruCache.containsKey(phone_num)) {
            return lruCache.get(phone_num);
        }
        try {
            Connection conn = JDBCCacheBean.getInstance();
            synchronized (this) {
                id = execSQL(conn, sql, phone_num);
            }
            lruCache.put(phone_num, id);
            return id;
        } catch (Exception e) {
            e.printStackTrace();
            throw new IOException(e);
        }

    }
}
